package com.lemon.cloud.gray.nacos;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.nacos.api.naming.listener.Event;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.lemon.cloud.comm.constants.GrayConstant;
import com.lemon.cloud.config.NacosWatchEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.core.env.Environment;

import java.util.List;

@Slf4j
public class GrayEvent implements NacosWatchEvent {

    @Override
    public String getKey() {
        return "gray.rule.enabled";
    }

    @Override
    public boolean accept(String value) {
        return "true".equals(value);
    }

    @Override
    public void doEvent(Event event) {
        Environment environment = SpringUtil.getBean(Environment.class);
        String appName = environment.getProperty(NacosWatchEvent.APP_NAME);
        String port = environment.getProperty(NacosWatchEvent.APP_PORT);
        if (StrUtil.isEmpty(appName) || StrUtil.isEmpty(port)){
            log.error("nacos watch APP_NAME or APP_PORT is null");
            return;
        }
        if (event instanceof NamingEvent) {
            List<Instance> instances = ((NamingEvent) event).getInstances();
            String ip = getIp();
            instances.forEach(i -> {
                if (isCurrInstance(i,ip,port) && isCurrService(i,appName)){
                    String grayFlag = i.getMetadata().get(GrayConstant.GRAY_FLAG);
                    if (StrUtil.isNotEmpty(grayFlag)&&
                            !grayFlag.equals(System.getProperty(GrayConstant.GRAY_FLAG))){
                        log.warn("实例:{}，ip:{},port:{}，是否灰度实例:{}", appName, i.getIp(),port,grayFlag);
                        System.setProperty(GrayConstant.GRAY_FLAG,grayFlag);
                    }
                }
            });
        }
    }

    private String getIp(){
        InetUtils inetUtils = SpringUtil.getBean(InetUtils.class);
        return inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
    }

    private boolean isCurrInstance(Instance i,String ip,String port){
        return ip.equals(i.getIp()) && port.equals(String.valueOf(i.getPort()));
    }

    private boolean isCurrService(Instance i,String appName){
        return StrUtil.isNotEmpty(i.getServiceName())&&
                i.getServiceName().contains(StrUtil.AT+appName);
    }
}
